package com.dsl.dslallinone.core;

import com.dsl.dslallinone.common.config.FilterConfig;
import com.dsl.dslallinone.common.config.MetricConfig;
import com.dsl.dslallinone.common.config.OrderConfig;
import com.dsl.dslallinone.dto.DslQuery;
import com.dsl.dslallinone.dto.TimeWindow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * DSL SQL构建器
 */
@Component
public class DslSqlBuilder {

    @Autowired
    private FuncRegistry funcRegistry;

    @Autowired
    private FactTableResolver factTableResolver;

    @Autowired
    private TimeBucketSql timeBucketSql;

    /**
     * 构建SQL
     */
    public String buildSql(DslQuery query) {
        // 解析表名
        String tableName = factTableResolver.resolveTable(query);

        // 构建SELECT子句
        String selectClause = buildSelectClause(query, tableName);

        // 构建FROM子句
        String fromClause = buildFromClause(tableName);

        // 构建WHERE子句
        String whereClause = buildWhereClause(query);

        // 构建GROUP BY子句
        String groupByClause = buildGroupByClause(query);

        // 构建ORDER BY子句
        String orderByClause = buildOrderByClause(query);

        // 构建LIMIT子句
        String limitClause = buildLimitClause(query);

        // 组装完整SQL
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT ").append(selectClause);
        sql.append(" FROM ").append(fromClause);
        if (!whereClause.isEmpty()) {
            sql.append(" WHERE ").append(whereClause);
        }
        if (!groupByClause.isEmpty()) {
            sql.append(" GROUP BY ").append(groupByClause);
        }
        if (!orderByClause.isEmpty()) {
            sql.append(" ORDER BY ").append(orderByClause);
        }
        if (!limitClause.isEmpty()) {
            sql.append(" LIMIT ").append(limitClause);
        }

        return sql.toString();
    }

    /**
     * 构建SELECT子句
     */
    private String buildSelectClause(DslQuery query, String tableName) {
        List<String> selectItems = new ArrayList<>();

        // 添加时间桶
        String timeBucket = timeBucketSql.buildTimeBucket(query.getTime().getGranularity());
        selectItems.add(timeBucket + " AS time_bucket");

        // 添加维度字段
        if (query.getDimensions() != null) {
            selectItems.addAll(query.getDimensions());
        }

        // 添加分组字段
        if (query.getGroupBy() != null) {
            for (String groupField : query.getGroupBy()) {
                if (!selectItems.contains(groupField)) {
                    selectItems.add(groupField);
                }
            }
        }

        // 添加指标字段
        for (MetricConfig metric : query.getMetrics()) {
            FuncRegistry.SqlFunction function = funcRegistry.getFunction(metric.getFn());
            String metricSql = function.buildSql(metric, query, tableName);
            selectItems.add(metricSql);
        }

        return String.join(", ", selectItems);
    }

    /**
     * 构建FROM子句
     */
    private String buildFromClause(String tableName) {
        return tableName;
    }

    /**
     * 构建WHERE子句
     */
    private String buildWhereClause(DslQuery query) {
        List<String> conditions = new ArrayList<>();

        // 添加时间范围条件
        TimeWindow window = query.getTime().getWindow();
        conditions.add(String.format("stat_date >= '%s'", window.getStart()));
        conditions.add(String.format("stat_date <= '%s'", window.getEnd()));

        // 添加删除标记条件
        conditions.add("is_del = 0");

        // 添加过滤条件
        if (query.getFilter() != null) {
            for (FilterConfig filter : query.getFilter()) {
                String condition = buildFilterCondition(filter);
                conditions.add(condition);
            }
        }

        return String.join(" AND ", conditions);
    }

    /**
     * 构建过滤条件
     */
    private String buildFilterCondition(FilterConfig filter) {
        String field = filter.getField();
        String op = filter.getOp();
        Object value = filter.getValue();

        switch (op.toLowerCase()) {
            case "eq":
                return String.format("%s = '%s'", field, value);
            case "ne":
                return String.format("%s != '%s'", field, value);
            case "gt":
                return String.format("%s > %s", field, value);
            case "gte":
                return String.format("%s >= %s", field, value);
            case "lt":
                return String.format("%s < %s", field, value);
            case "lte":
                return String.format("%s <= %s", field, value);
            case "in":
                if (value instanceof List) {
                    List<?> values = (List<?>) value;
                    String inValues = values.stream()
                            .map(v -> "'" + v + "'")
                            .collect(Collectors.joining(", "));
                    return String.format("%s IN (%s)", field, inValues);
                }
                return String.format("%s IN ('%s')", field, value);
            case "like":
                return String.format("%s LIKE '%%%s%%'", field, value);
            default:
                throw new IllegalArgumentException("不支持的操作符: " + op);
        }
    }

    /**
     * 构建GROUP BY子句
     */
    private String buildGroupByClause(DslQuery query) {
        List<String> groupFields = new ArrayList<>();

        // 添加时间桶分组
        groupFields.add("time_bucket");

        // 添加维度分组
        if (query.getDimensions() != null) {
            groupFields.addAll(query.getDimensions());
        }

        // 添加指定分组字段
        if (query.getGroupBy() != null) {
            for (String groupField : query.getGroupBy()) {
                if (!groupFields.contains(groupField)) {
                    groupFields.add(groupField);
                }
            }
        }

        return String.join(", ", groupFields);
    }

    /**
     * 构建ORDER BY子句
     */
    private String buildOrderByClause(DslQuery query) {
        List<String> orderItems = new ArrayList<>();

        if (query.getOrderBy() != null && !query.getOrderBy().isEmpty()) {
            for (OrderConfig order : query.getOrderBy()) {
                orderItems.add(order.getField() + " " + order.getDir().toUpperCase());
            }
        } else {
            // 默认按时间排序
            orderItems.add("time_bucket ASC");
        }

        return String.join(", ", orderItems);
    }

    /**
     * 构建LIMIT子句
     */
    private String buildLimitClause(DslQuery query) {
        if (query.getLimit() != null && query.getLimit() > 0) {
            return String.valueOf(query.getLimit());
        }
        return "";
    }
}
